package org.example.springboot.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import org.example.springboot.entity.Book;
import org.example.springboot.entity.Rating;
import org.example.springboot.exception.ServiceException;
import org.example.springboot.mapper.BookMapper;
import org.example.springboot.mapper.RatingMapper;
import org.example.springboot.util.JwtTokenUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 评分服务类
 */
@Service
public class RatingService {
    @Resource
    private RatingMapper ratingMapper;
    
    @Resource
    private BookMapper bookMapper;
    
    /**
     * 添加或更新评分
     * @param bookId 图书ID
     * @param score 评分
     * @return 评分ID
     */
    @Transactional(rollbackFor = Exception.class)
    public Long rateBook(Long bookId, Integer score) {
        // 获取当前用户ID
        Long userId = JwtTokenUtils.getCurrentUser().getId();
        
        // 检查图书是否存在
        Book book = bookMapper.selectById(bookId);
        if (book == null) {
            throw new ServiceException("图书不存在");
        }
        
        // 检查评分范围
        if (score < 1 || score > 5) {
            throw new ServiceException("评分必须在1-5之间");
        }
        
        // 检查是否已评分
        Rating existRating = ratingMapper.selectOne(
            new LambdaQueryWrapper<Rating>()
                .eq(Rating::getUserId, userId)
                .eq(Rating::getBookId, bookId)
        );
        
        if (existRating != null) {
            // 更新评分
            existRating.setScore(score);
            if (ratingMapper.updateById(existRating) <= 0) {
                throw new ServiceException("评分更新失败");
            }
            
            // 更新图书平均评分
            updateBookAvgScore(bookId);
            
            return existRating.getId();
        } else {
            // 创建新评分
            Rating rating = new Rating();
            rating.setUserId(userId);
            rating.setBookId(bookId);
            rating.setScore(score);
            
            if (ratingMapper.insert(rating) <= 0) {
                throw new ServiceException("评分失败");
            }
            
            // 更新图书平均评分
            updateBookAvgScore(bookId);
            
            return rating.getId();
        }
    }
    
    /**
     * 获取用户对图书的评分
     * @param bookId 图书ID
     * @return 评分，如果未评分则返回null
     */
    public Integer getUserRating(Long bookId) {
        // 获取当前用户ID
        Long userId = JwtTokenUtils.getCurrentUser().getId();
        
        Rating rating = ratingMapper.selectOne(
            new LambdaQueryWrapper<Rating>()
                .eq(Rating::getUserId, userId)
                .eq(Rating::getBookId, bookId)
                .select(Rating::getScore)
        );
        
        return rating != null ? rating.getScore() : null;
    }
    
    /**
     * 更新图书平均评分
     * @param bookId 图书ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateBookAvgScore(Long bookId) {
        // 查询图书所有评分
        List<Rating> ratings = ratingMapper.selectList(
            new LambdaQueryWrapper<Rating>()
                .eq(Rating::getBookId, bookId)
                .select(Rating::getScore)
        );
        
        if (ratings.isEmpty()) {
            // 没有评分，设置为0
            Book book = new Book();
            book.setId(bookId);
            book.setAvgScore(BigDecimal.ZERO);
            bookMapper.updateById(book);
            return;
        }
        
        // 计算平均评分
        double avgScore = ratings.stream()
            .mapToInt(Rating::getScore)
            .average()
            .orElse(0);
        
        // 四舍五入到一位小数
        BigDecimal roundedAvgScore = BigDecimal.valueOf(avgScore)
            .setScale(1, RoundingMode.HALF_UP);
        
        // 更新图书平均评分
        Book book = new Book();
        book.setId(bookId);
        book.setAvgScore(roundedAvgScore);
        bookMapper.updateById(book);
    }
    
    /**
     * 获取用户评分过的所有图书ID
     * @param userId 用户ID
     * @return 图书ID列表
     */
    public List<Long> getUserRatedBookIds(Long userId) {
        return ratingMapper.selectList(
            new LambdaQueryWrapper<Rating>()
                .eq(Rating::getUserId, userId)
                .select(Rating::getBookId)
        ).stream().map(Rating::getBookId).toList();
    }
} 